热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

提案|主体_以贡献飞桨框架API为例,手把手教你从User进阶到Contributor

篇首语:本文由编程笔记#小编为大家整理,主要介绍了以贡献飞桨框架API为例,手把手教你从User进阶到Contributor相关的知识,希望对你有一定的参考价值。

篇首语:本文由编程笔记#小编为大家整理,主要介绍了以贡献飞桨框架API为例,手把手教你从User进阶到Contributor相关的知识,希望对你有一定的参考价值。



2016年9月,飞桨框架正式开源。飞桨框架建设并非只靠百度工程师,也离不开热爱飞桨、热爱开源的开发者们,他们用自己的方式参与飞桨框架建设,与飞桨共同成长。作为大型开源项目,飞桨社区十分欢迎各位开发者积极提出需求或不足,并主动提交pr解决。本文将由开发者李其睿介绍贡献API的经验。



前段时间百度飞桨组织了飞桨黑客马拉松第三期活动,该活动发布了诸多有趣的开发任务。我参与了基础API方向的开发任务,并新增了paddle.triu_indices API。这个API可以获取一个Tensor主对角线所有右上方元素的坐标,在不久前发布的飞桨2.4版本中已经上线(官方文档)。借此机会记录一下开发过程,供有兴趣为飞桨贡献的小伙伴入门参考。


感兴趣的同学可以直接参考PR:


  • 飞桨代码

    https://github.com/PaddlePaddle/Paddle/pull/45168

  • 文档

    https://github.com/PaddlePaddle/docs/pull/5161

  • 提案

    https://github.com/PaddlePaddle/community/pull/207



一个API背后的组成


由于飞桨核心是由C++构建的,通过Python封装了API供用户使用,因此每个API均对应着Python部分的代码和C++部分的代码,以下将分开介绍。


C++部分


现在飞桨的算子库核心代码都在paddle/phi这个目录下。


  • paddle/phi/kernels: 这个目录下是算子的实现部分,分别需要实现“.h”文件(头文件)、 “.cc”文件(CPU算子)、“.cu”文件(GPU算子) 这三个部分;

  • paddle/phi/infermeta: 这个目录下的文件是推理一个API的输出参数的meta数据,例如:数据维度、数据type等。该目录下有多个文件,根据算子输入Tensor的参数数量确定InferMeta函数放置位置,比如算子输入Tensor参数是0个,那推理函数需要放在nullary.cc/h中;如果是Tensor参数有2个,则需要放在binary.cc/h中;

  • paddle/phi/api/yaml:这个目录下是用以注册API属性的yaml文件,需要在yaml文件中添加你新增API的一些属性信息。


Python部分


Python部分相对而言内容比较少了,主要在python/paddle目录下。


  • python/paddle/tensor/creation.py: 这个文件主要是用来构造该API在Python端调用时的接口,其中包含了入参的校验、算子的调用过程。另外英文版的API文档也在这里进行编写;

  • python/paddle/_init_.py:初始化文件;

  • python/paddle/fluid/tests/unittests/test_xxxx.py:单测文件。


文档


一个API的完整构建,除了代码的开发外,其文档的撰写也是非常必要的。飞桨的中文文档位于PaddlePaddle/docs仓库中。


  • docs/api/paddle/Overview_cn.rst中用一句话对API的功能进行简要概述;

  • docs/api/paddle/xxxxx_cn.rst对于新增的API,需要新增一个rst文件进行文档撰写,撰写内容包括API的输入、输出、代码示例等。



撰写提案


当着手开发一个新的API时,第一步不是写代码,而是进行分析和设计。


关于设计,有以下几点需要注意:


  • 飞桨的现状。想要实现的API是否不存在、是否可以由其他API组合方式实现?

  • 业内是否有此API?例如PyTorch、NumPy、TensorFlow等,如果有的话他们是怎么实现的?哪种实现方式更好?

  • 飞桨中新增的这个API的命名、参数设计。

  • 测试方案设计。


作为社区开发者,我们可以综合上述几点将设计写成文档,提交至Coummunity库,与飞桨的工程师沟通、调整并确定方案。



正式开发


拉代码并成功编译


  • 首先在Paddle仓库的GitHub页面上fork一份代码;

  • 最方便的搭建开发环境的办法就是使用飞桨官方提供的Docker镜像; 



  • 然后在Docker镜像内clone,并切换到develop分支(最好在做每个任务时从develop分支checkout一个新分支,会更方便)。


顺利的话到此就编译成功。编译好的whl文件在 /paddle/build/python/dist目录下,进入目录使用pip install安装。


以后修改完代码就重复执行make、pip3 install的过程即可。


到此就可以正式开始写代码


第一步:首先需要实现最核心的kernel部分。


让我们从最简单的部分开始,头文件triu_indices_kernel.h。头文件通常不需要写主要的代码逻辑,只要注册好方法就好。


第二步:接下来需要实现CPU端的代码逻辑triu_indices_kernel.cc。


CPU端的主体的计算逻辑其实并不复杂,这里对代码的几个注意点进行说明:


  • kernel需要在phi这个命名空间下;

  • 受Python书写习惯影响,有时会输出return。更好的方式是将输出需要用到的内存分配后作为参数传入kernel;

  • 需要多关注边界条件,以及不要受惯性思维限制。比如Tensor不一定是正方形,对角线也不一定是主对角线,对于这类非常规情况的处理需要格外注意,这些情况可能也是需要代码量最多的地方(如下图所示);

  • 最后通过PD_REGISTER_KERNEL注册算子。 



第三步:接下来需要实现GPU端的kernel:triu_indices_kernel.cu。


编写GPU kernel需要有一点CUDA的基础知识,这里需要稍加学习,理解基础的概念。如果零基础的话,指路比较好的入门资料如下:


  • 一个入门博客:


https://face2ai.com/program-blog/#GPU编程(CUDA);


  • 两本入门书:《CUDA By Example》《Professional CUDA C Programming》


在编写GPU kernel时,我们需要抛弃掉往常写代码线性执行代码的思想,将整个计算任务展开成一个计算组。有许许多多个worker帮我们,每个worker只需要负责很小一部分数据计算即可。当转变成并行计算的思想后,代码编写和理解就会稍微简单一些。


由于整体的kernel代码较长,这里不再另作展示,有需求的可自行前往代码库里查看。


第四步:写完两个kernel,最难的部分就结束了,下面该写配套代码了。


首先是推理meta信息所在:nullary.cc和nullary.h。这一步很简单,在nullary.h里进行函数声明,在nullary.cc里实现具体推理meta信息的逻辑。.cc文件内较为复杂的是需要计算输出的shape,当输入是正方形,对角线就是主对角线,其计算很简单。但当输入是矩形,对角线进行了向上或向下平移的话则需要考虑不同的情况。


第五步:最后一项工作就是注册算子。在legacy_api.yaml中添加信息(最新develop已经更新为legacy_op.yaml)。


根据格式规范,写清楚API的名字、参数等重要信息。


第六步:下面就是轻松的Python代码环节。首先说核心的creation.py。


这里定义的函数格式就是以后使用该API过程中交互的格式。


def triu_indices(row, col=None, offset=0, dtype='int64'):
    """
    英文文档部分
"""
# 校验各入参类型
# 根据计算图类型引用算子
# 返回计算结果
        )
    return out

其中主要做的是例如参数校验、与op交互等过程。另外,这里的文档编写是直接展示在英文版飞桨文档网页的,需要认真编写。编写完成后,在__init__.py中导入即可。


到这里API主体代码就全部完成了,可以执行make、pip install去进行测试了。这里可以先试验,体验一下自己的工作成果。


import paddle
data1 = paddle.triu_indices(4,4,0)
print(data1)
Tensor(shape=[2, 10], dtype=int64, place=Place(cpu), stop_gradient=True,
Output:
       [[0, 0, 0, 0, 1, 1, 1, 2, 2, 3],
        [0, 1, 2, 3, 1, 2, 3, 2, 3, 3]])

单测的编写


简单的体验看起来是没问题的,下面需要编写详尽的单测案例来进行测试。主要测试以下几项:


  • 函数功能在各种参数配置下是否都正确,可以与NumPy、PyTorch进行比较;

  • 函数在动态图、静态图中是否都可以正常使用;

  • 函数是否能正常报错。


当所有的单测都通过,API的代码开发就基本完成了。只剩最后一项,编写中文文档。


文档编写


文档主要内容包括API的功能、接口形式、入参/出参的具体含义和格式以及使用示例。这几部分内容和英文文档几乎可以一一对应,写完一个可再翻译另一个。



到此,整个API开发的流程就结束了。通常在开发编译时会反复报错、debug、修改代码、重试,这些过程是必不可少的,最终体验到的喜悦也是难以言表的。


如果你也想加入开源、体验贡献开源的乐趣,快来参加👇


飞桨快乐开源活动:快来提PR,领取新年礼物啦


为鼓励更多的开发者参与到飞桨社区的开源建设中,帮助社区修复bug或贡献feature,加入开源、共建飞桨。飞桨快乐开源活动暖冬来袭,我们提供了三种类型的贡献任务,并为完成任务的贡献者准备了礼品表示感谢!


如果你对提PR仍有问题,欢迎在评论区留言扫描下方图片二维码沟通咨询~




关注【飞桨PaddlePaddle】公众号


获取更多技术内容~


推荐阅读
  • 如何更换Anaconda和pip的国内镜像源
    本文详细介绍了如何通过国内多个知名镜像站(如北京外国语大学、中国科学技术大学、阿里巴巴等)更换Anaconda和pip的源,以提高软件包的下载速度和安装效率。 ... [详细]
  • 尤洋:夸父AI系统——大规模并行训练的深度学习解决方案
    自从AlexNet等模型在计算机视觉领域取得突破以来,深度学习技术迅速发展。近年来,随着BERT等大型模型的广泛应用,AI模型的规模持续扩大,对硬件提出了更高的要求。本文介绍了新加坡国立大学尤洋教授团队开发的夸父AI系统,旨在解决大规模模型训练中的并行计算挑战。 ... [详细]
  • 本文详细介绍了 Node.js 中 OS 模块的 arch 方法,包括其功能、语法、参数以及返回值,并提供了具体的使用示例。 ... [详细]
  • 本文由技术爱好者痞子衡撰写,详细介绍了一款名为pzh-speech的语音处理工具的开发背景与核心技术。该工具旨在简化语音处理流程,为开发者提供一个强大的开源解决方案。 ... [详细]
  • 本文旨在介绍一系列提升工作效率的浏览器插件和实用小工具,帮助用户在日常工作中更加便捷高效。内容由原作者授权发布。 ... [详细]
  • 深入解析轻量级数据库 SQL Server Express LocalDB
    本文详细介绍了 SQL Server Express LocalDB,这是一种轻量级的本地 T-SQL 数据库解决方案,特别适合开发环境使用。文章还探讨了 LocalDB 与其他轻量级数据库的对比,并提供了安装和连接 LocalDB 的步骤。 ... [详细]
  • 本文探讨了Android系统中联系人数据库的设计,特别是AbstractContactsProvider类的作用与实现。文章提供了对源代码的详细分析,并解释了该类如何支持跨数据库操作及事务处理。源代码可从官方Android网站下载。 ... [详细]
  • 本文探讨了一个Web工程项目的需求,即允许用户随时添加定时任务,并通过Quartz框架实现这些任务的自动化调度。文章将介绍如何设计任务表以存储任务信息和执行周期,以及如何通过一个定期扫描机制自动识别并加载新任务到调度系统中。 ... [详细]
  • selenium通过JS语法操作页面元素
    做过web测试的小伙伴们都知道,web元素现在很多是JS写的,那么既然是JS写的,可以通过JS语言去操作页面,来帮助我们操作一些selenium不能覆盖的功能。问题来了我们能否通过 ... [详细]
  • STM32代码编写STM32端不需要写关于连接MQTT服务器的代码,连接的工作交给ESP8266来做,STM32只需要通过串口接收和发送数据,间接的与服务器交互。串口三配置串口一已 ... [详细]
  • 本文探讨了使用Python实现监控信息收集的方法,涵盖从基础的日志记录到复杂的系统运维解决方案,旨在帮助开发者和运维人员提升工作效率。 ... [详细]
  • SSE图像算法优化系列三:超高速导向滤波实现过程纪要(欢迎挑战)
    自从何凯明提出导向滤波后,因为其算法的简单性和有效性,该算法得到了广泛的应用,以至于新版的matlab都将其作为标准自带的函数之一了&#x ... [详细]
  • 本文详细介绍了如何在 Ubuntu 14.04 系统上搭建仅使用 CPU 的 Caffe 深度学习框架,包括环境准备、依赖安装及编译过程。 ... [详细]
  • 吴石访谈:腾讯安全科恩实验室如何引领物联网安全研究
    腾讯安全科恩实验室曾两次成功破解特斯拉自动驾驶系统,并远程控制汽车,展示了其在汽车安全领域的强大实力。近日,该实验室负责人吴石接受了InfoQ的专访,详细介绍了团队未来的重点方向——物联网安全。 ... [详细]
  • 七大策略降低云上MySQL成本
    在全球经济放缓和通胀压力下,降低云环境中MySQL数据库的运行成本成为企业关注的重点。本文提供了一系列实用技巧,旨在帮助企业有效控制成本,同时保持高效运作。 ... [详细]
author-avatar
桃花岛的小米_992
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有